package it.softphone.commons.json.server.jersey;

import it.softphone.commons.json.server.JSONException;
import it.softphone.commons.json.server.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;


import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider;

@Produces( { MediaType.APPLICATION_JSON })
@Consumes( { MediaType.APPLICATION_JSON })
@Provider
public abstract class JSONObjectProvider extends AbstractMessageReaderWriterProvider<it.softphone.commons.json.server.JSONObject> {

	protected void  log( String msg ) {
		//System.out.println(msg);
		
	}
	
	public boolean isSupported( Class<?> type ) {
		 return  JSONObject.class == type;
	}

	public boolean isReadable(Class<?> type, Type genericType, Annotation annotations[], MediaType mediaType) {
		return isSupported(type) && isSupported(mediaType);
	}

	public boolean isWriteable(Class<?> type, Type genericType, Annotation annotations[], MediaType mediaType) {
		boolean result =  isSupported(type) && isSupported(mediaType);
		log( "isWriteable " + type +  " " + result );
		return result;
	}

	protected boolean isSupported(MediaType m) {
		boolean result =  MediaType.APPLICATION_JSON_TYPE.equals(m);
		log( "isSupported " + m +  " " + result );
		return result;
	}

	public JSONObject readFrom(Class<JSONObject> type, Type genericType,
			Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
			throws IOException, WebApplicationException {
		try {
			return new JSONObject(readFromAsString(entityStream, mediaType));
		} catch (JSONException je) {
			throw new WebApplicationException(new Exception(
					"ERROR PARSING JSON OBJECT", je), 400);
		}
	}

	public void writeTo(JSONObject t, Class<?> type, Type genericType,
			Annotation annotations[], MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders,
			OutputStream entityStream) throws IOException {
		try {
			OutputStreamWriter writer = new OutputStreamWriter(entityStream,
					getCharset(mediaType));
			t.write(writer);
			writer.flush();
		} catch (JSONException je) {
			throw new WebApplicationException(new Exception(
					"ERROR WRITING JSON OBJECT", je), 500);
		}
	}
}
